package org.jeecg.modules.wo.persontype.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.YouBianCodeUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.wo.people.entity.WoPeople;
import org.jeecg.modules.wo.people.service.IWoPeopleService;
import org.jeecg.modules.wo.persontype.entity.WoPersonType;
import org.jeecg.modules.wo.persontype.entity.WoPersonTypeTree;
import org.jeecg.modules.wo.persontype.mapper.WoPersonTypeMapper;
import org.jeecg.modules.wo.persontype.service.IWoPersonTypeService;
import org.jeecg.modules.wo.utils.KyqApiUtils;
import org.jeecg.modules.wo.wobasepeople.entity.WoBasePeople;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.*;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * @Description: 人员类别信息
 * @Author: jeecg-boot
 * @Date:   2022-03-22
 * @Version: V1.0
 */
@Service
public class WoPersonTypeServiceImpl extends ServiceImpl<WoPersonTypeMapper, WoPersonType> implements IWoPersonTypeService {
    @Autowired
    private IWoPeopleService woPeopleService;
	@Override
	public void addWoPersonType(WoPersonType woPersonType) {
	   //新增时设置hasChild为0
	    woPersonType.setHasChild(IWoPersonTypeService.NOCHILD);
        //生成本节点编码
        woPersonType.setTypeCode(makeTypeCode(woPersonType.getPid()));
		if(oConvertUtils.isEmpty(woPersonType.getPid())){
			woPersonType.setPid(IWoPersonTypeService.ROOT_PID_VALUE);
		}else{
			//如果当前节点父ID不为空 则设置父节点的hasChildren 为1
			WoPersonType parent = baseMapper.selectById(woPersonType.getPid());
			if(parent!=null && !"1".equals(parent.getHasChild())){
				parent.setHasChild("1");
				baseMapper.updateById(parent);
			}
		}
		baseMapper.insert(woPersonType);
	}
    private String makeTypeCode(String pid){
        WoPersonType fType=this.getById(pid);//查询父节点，获取父级编码
        QueryWrapper<WoPersonType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid",pid);
        queryWrapper.orderByDesc("type_code");
        queryWrapper.last("LIMIT 1");
        WoPersonType lType=this.getOne(queryWrapper);//查询同级编码最大的，已获取当前同级最大编码
        String  lCode=null;
        if(lType!=null){
            lCode=lType.getTypeCode();
        }
        //YouBianCodeUtil.getSubYouBianCode("A05","A05A01"); //生成的编码为A05A02
        //生成本节点编码
        String fCode=fType.getTypeCode();
        if("root".equals(fCode)){
            fCode="";
        }
       return YouBianCodeUtil.getSubYouBianCode(fCode,lCode);
    }

	@Override
	public void updateWoPersonType(WoPersonType woPersonType) {
		WoPersonType entity = this.getById(woPersonType.getId());
		if(entity==null) {
			throw new JeecgBootException("未找到对应实体");
		}
		String old_pid = entity.getPid();
		String new_pid = woPersonType.getPid();
		if(!old_pid.equals(new_pid)) {//如果更换了父级
			updateOldParentNode(old_pid);
			if(oConvertUtils.isEmpty(new_pid)){
				woPersonType.setPid(IWoPersonTypeService.ROOT_PID_VALUE);
			}
			if(!IWoPersonTypeService.ROOT_PID_VALUE.equals(woPersonType.getPid())) {
				baseMapper.updateTreeNodeStatus(woPersonType.getPid(), IWoPersonTypeService.HASCHILD);
			}
			//重新生成编码
            woPersonType.setTypeCode(makeTypeCode(new_pid));
		}
		baseMapper.updateById(woPersonType);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void deleteWoPersonType(String id) throws JeecgBootException {
		//查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if(id.indexOf(",")>0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if(idVal != null){
                    WoPersonType woPersonType = this.getById(idVal);
                    String pidVal = woPersonType.getPid();
                    //查询此节点上一级是否还有其他子节点
                    List<WoPersonType> dataList = baseMapper.selectList(new QueryWrapper<WoPersonType>().eq("pid", pidVal).notIn("id",Arrays.asList(idArr)));
                    if((dataList == null || dataList.size()==0) && !Arrays.asList(idArr).contains(pidVal)
                            && !sb.toString().contains(pidVal)){
                        //如果当前节点原本有子节点 现在木有了，更新状态
                        sb.append(pidVal).append(",");
                    }
                }
            }
            //批量删除节点
            baseMapper.deleteBatchIds(Arrays.asList(idArr));
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for(String pid : pidArr){
                this.updateOldParentNode(pid);
            }
        }else{
            WoPersonType woPersonType = this.getById(id);
            if(woPersonType==null) {
                throw new JeecgBootException("未找到对应实体");
            }
            updateOldParentNode(woPersonType.getPid());
            baseMapper.deleteById(id);
        }
	}

	@Override
    public List<WoPersonType> queryTreeListNoPage(QueryWrapper<WoPersonType> queryWrapper) {
        List<WoPersonType> dataList = baseMapper.selectList(queryWrapper);
        List<WoPersonType> mapList = new ArrayList<>();
        for(WoPersonType data : dataList){
            String pidVal = data.getPid();
            //递归查询子节点的根节点
            if(pidVal != null && !"0".equals(pidVal)){
                WoPersonType rootVal = this.getTreeRoot(pidVal);
                if(rootVal != null && !mapList.contains(rootVal)){
                    mapList.add(rootVal);
                }
            }else{
                if(!mapList.contains(data)){
                    mapList.add(data);
                }
            }
        }
        return mapList;
    }

    @Override
    public List<WoPersonTypeTree> queryTreeList(QueryWrapper<WoPersonType> queryWrapper) {
        LoginUser loginUser= (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String userNucleic=loginUser.getNucleic();
        userNucleic.replaceAll("，",",");//将中文逗号换成英文逗号
        queryWrapper.in("type_code",userNucleic.split(","));
        List<WoPersonType> dataList = baseMapper.selectList(queryWrapper);
        List<WoPersonTypeTree> mapList = new ArrayList<>();
        //根类别
        for(WoPersonType data : dataList){
            WoPersonTypeTree type=new WoPersonTypeTree(data);
            type.setRoot(true);
            //递归查询子节点
            type.setChildren(this.queryChildren(type));
            mapList.add(type);
        }
        return mapList;
    }
    private List<WoPersonTypeTree> queryChildren(WoPersonTypeTree type){
        QueryWrapper<WoPersonType> childrenQueryWrapper=new QueryWrapper<>();
        childrenQueryWrapper.eq("pid",type.getId());
        List<WoPersonType> list = baseMapper.selectList(childrenQueryWrapper);
        List<WoPersonTypeTree> childrenList=new ArrayList<>();
        for(WoPersonType ptype:list){
            WoPersonTypeTree ctype=new WoPersonTypeTree(ptype);
            ctype.setChildren(this.queryChildren(ctype));
            childrenList.add(ctype);
        }
        return childrenList;
    }
    /**
	 * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
	 * @param pid
	 */
	private void updateOldParentNode(String pid) {
		if(!IWoPersonTypeService.ROOT_PID_VALUE.equals(pid)) {
			Integer count = baseMapper.selectCount(new QueryWrapper<WoPersonType>().eq("pid", pid));
			if(count==null || count<=1) {
				baseMapper.updateTreeNodeStatus(pid, IWoPersonTypeService.NOCHILD);
			}
		}
	}

	/**
     * 递归查询节点的根节点
     * @param pidVal
     * @return
     */
    private WoPersonType getTreeRoot(String pidVal){
        WoPersonType data =  baseMapper.selectById(pidVal);
        if(data != null && !"0".equals(data.getPid())){
            return this.getTreeRoot(data.getPid());
        }else{
            return data;
        }
    }

    /**
     * 根据id查询所有子节点id
     * @param ids
     * @return
     */
    public String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if(pidVal != null){
                if(!sb.toString().contains(pidVal)){
                    if(sb.toString().length() > 0){
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal,sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 核酸检测统计
     * @param woPersonType
     * @return
     */
    @Override
    public Map nucleicCnt(WoPersonType woPersonType,int day) {
        Map rsMap=JSON.parseObject(JSON.toJSONString(woPersonType), Map.class);
        //查询改分组总人数
        QueryWrapper<WoPeople> allWrapper =new QueryWrapper<>();
        QueryWrapper<WoPeople> yWrapper  =new QueryWrapper<>();
        String ids=this.queryTreeChildIds(woPersonType.getId());
        allWrapper.in("psn_type_id",ids.split(","));
        Integer allCnt=woPeopleService.count(allWrapper);
        rsMap.put("allCnt",allCnt);
        //查询已做 核酸检测人数
        yWrapper.in("psn_type_id",ids.split(","));
        Date now=new Date();
        int s = day*24*60*60;// 将day天转换为秒
        Date bTime=DateUtils.addTime(now,Calendar.SECOND,-s);
        yWrapper.between("nucleic_date", bTime,now);
        Integer yCnt=woPeopleService.count(yWrapper);
        rsMap.put("yCnt",yCnt);
        rsMap.put("nCnt",allCnt-yCnt);
        String yScale="0";
        if(yCnt>0){
            DecimalFormat decimalFormat = new DecimalFormat("0.00%");
            yScale= decimalFormat.format((float) yCnt / (float) allCnt);
        }
        rsMap.put("yScale",yScale);
        return rsMap;
    }
    /**
     * 递归查询所有子节点
     * @param pidVal
     * @param sb
     * @return
     */
    public StringBuffer getTreeChildIds(String pidVal,StringBuffer sb){
        List<WoPersonType> dataList = baseMapper.selectList(new QueryWrapper<WoPersonType>().eq("pid", pidVal));
        if(dataList != null && dataList.size()>0){
            for(WoPersonType tree : dataList) {
                if(!sb.toString().contains(tree.getId())){
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(),sb);
            }
        }
        return sb;
    }
}
